package com.cyx.exercise.ollama;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;

/**
 * Ollama客户端对比工具类
 * 展示现代HttpClient和传统URLConnection两种实现的差异
 */
public class OllamaClientComparison {
    
    private final OllamaClient modernClient;
    private final OllamaClientLegacy legacyClient;
    private final String testModel;
    
    public OllamaClientComparison(String baseUrl, String testModel) {
        this.modernClient = new OllamaClient(baseUrl);
        this.legacyClient = new OllamaClientLegacy(baseUrl);
        this.testModel = testModel;
    }
    
    /**
     * 运行完整的对比测试
     */
    public void runComparison() {
        System.out.println("=== Ollama客户端实现对比测试 ===\n");
        
        try {
            // 1. 连接测试
            testConnection();
            
            // 2. 同步调用性能对比
            testSyncPerformance();
            
            // 3. 异步调用对比
            testAsyncPerformance();
            
            // 4. 聊天接口对比
            testChatComparison();
            
            // 5. 错误处理对比
            testErrorHandling();
            
        } catch (Exception e) {
            System.err.println("对比测试出错: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 清理资源
            legacyClient.close();
        }
        
        System.out.println("=== 对比测试完成 ===");
    }
    
    /**
     * 连接测试
     */
    private void testConnection() {
        System.out.println("1. 连接测试对比");
        System.out.println("----------------------------------------");
        
        // 现代客户端连接测试
        try {
            long startTime = System.currentTimeMillis();
            String modernModels = modernClient.getModels();
            long modernTime = System.currentTimeMillis() - startTime;
            System.out.println("✓ 现代HttpClient连接成功，耗时: " + modernTime + "ms");
            System.out.println("  模型数据长度: " + modernModels.length() + " 字符");
        } catch (Exception e) {
            System.err.println("✗ 现代HttpClient连接失败: " + e.getMessage());
        }
        
        // 传统客户端连接测试
        try {
            long startTime = System.currentTimeMillis();
            String legacyModels = legacyClient.getModels();
            long legacyTime = System.currentTimeMillis() - startTime;
            System.out.println("✓ 传统URLConnection连接成功，耗时: " + legacyTime + "ms");
            System.out.println("  模型数据长度: " + legacyModels.length() + " 字符");
        } catch (Exception e) {
            System.err.println("✗ 传统URLConnection连接失败: " + e.getMessage());
        }
        
        System.out.println();
    }
    
    /**
     * 同步调用性能对比
     */
    private void testSyncPerformance() {
        System.out.println("2. 同步调用性能对比");
        System.out.println("----------------------------------------");
        
        String testPrompt = "用一句话解释什么是HTTP协议";
        
        // 现代客户端同步调用
        try {
            OllamaRequest request = new OllamaRequest(testModel, testPrompt);
            long startTime = System.currentTimeMillis();
            OllamaResponse modernResponse = modernClient.generate(request);
            long modernTime = System.currentTimeMillis() - startTime;
            
            System.out.println("现代HttpClient同步调用:");
            System.out.println("  耗时: " + modernTime + "ms");
            System.out.println("  响应长度: " + modernResponse.getResponse().length() + " 字符");
            System.out.println("  响应预览: " + truncateString(modernResponse.getResponse(), 100));
        } catch (Exception e) {
            System.err.println("现代HttpClient同步调用失败: " + e.getMessage());
        }
        
        // 传统客户端同步调用
        try {
            OllamaRequest request = new OllamaRequest(testModel, testPrompt);
            long startTime = System.currentTimeMillis();
            OllamaResponse legacyResponse = legacyClient.generate(request);
            long legacyTime = System.currentTimeMillis() - startTime;
            
            System.out.println("传统URLConnection同步调用:");
            System.out.println("  耗时: " + legacyTime + "ms");
            System.out.println("  响应长度: " + legacyResponse.getResponse().length() + " 字符");
            System.out.println("  响应预览: " + truncateString(legacyResponse.getResponse(), 100));
        } catch (Exception e) {
            System.err.println("传统URLConnection同步调用失败: " + e.getMessage());
        }
        
        System.out.println();
    }
    
    /**
     * 异步调用对比
     */
    private void testAsyncPerformance() {
        System.out.println("3. 异步调用对比");
        System.out.println("----------------------------------------");
        
        String testPrompt = "列举3个Java的特点";
        
        try {
            OllamaRequest request = new OllamaRequest(testModel, testPrompt);
            
            // 现代客户端异步调用
            long modernStartTime = System.currentTimeMillis();
            CompletableFuture<OllamaResponse> modernFuture = modernClient.generateAsync(request);
            
            // 传统客户端异步调用
            long legacyStartTime = System.currentTimeMillis();
            CompletableFuture<OllamaResponse> legacyFuture = legacyClient.generateAsync(request);
            
            // 等待两个异步调用完成
            CompletableFuture.allOf(modernFuture, legacyFuture).join();
            
            // 处理现代客户端结果
            OllamaResponse modernResponse = modernFuture.get();
            long modernTime = System.currentTimeMillis() - modernStartTime;
            System.out.println("现代HttpClient异步调用:");
            System.out.println("  总耗时: " + modernTime + "ms");
            System.out.println("  响应长度: " + modernResponse.getResponse().length() + " 字符");
            
            // 处理传统客户端结果
            OllamaResponse legacyResponse = legacyFuture.get();
            long legacyTime = System.currentTimeMillis() - legacyStartTime;
            System.out.println("传统URLConnection异步调用:");
            System.out.println("  总耗时: " + legacyTime + "ms");
            System.out.println("  响应长度: " + legacyResponse.getResponse().length() + " 字符");
            
        } catch (Exception e) {
            System.err.println("异步调用对比失败: " + e.getMessage());
        }
        
        System.out.println();
    }
    
    /**
     * 聊天接口对比
     */
    private void testChatComparison() {
        System.out.println("4. 聊天接口对比");
        System.out.println("----------------------------------------");
        
        // 现代客户端聊天
        try {
            OllamaChatRequest request = new OllamaChatRequest(testModel);
            request.addSystemMessage("你是一个简洁的助手");
            request.addUserMessage("什么是RESTful API？");
            
            long startTime = System.currentTimeMillis();
            OllamaChatResponse modernResponse = modernClient.chat(request);
            long modernTime = System.currentTimeMillis() - startTime;
            
            System.out.println("现代HttpClient聊天接口:");
            System.out.println("  耗时: " + modernTime + "ms");
            System.out.println("  角色: " + modernResponse.getMessage().getRole());
            System.out.println("  响应预览: " + truncateString(modernResponse.getMessage().getContent(), 100));
        } catch (Exception e) {
            System.err.println("现代HttpClient聊天接口失败: " + e.getMessage());
        }
        
        // 传统客户端聊天
        try {
            OllamaChatRequest request = new OllamaChatRequest(testModel);
            request.addSystemMessage("你是一个简洁的助手");
            request.addUserMessage("什么是RESTful API？");
            
            long startTime = System.currentTimeMillis();
            OllamaChatResponse legacyResponse = legacyClient.chat(request);
            long legacyTime = System.currentTimeMillis() - startTime;
            
            System.out.println("传统URLConnection聊天接口:");
            System.out.println("  耗时: " + legacyTime + "ms");
            System.out.println("  角色: " + legacyResponse.getMessage().getRole());
            System.out.println("  响应预览: " + truncateString(legacyResponse.getMessage().getContent(), 100));
        } catch (Exception e) {
            System.err.println("传统URLConnection聊天接口失败: " + e.getMessage());
        }
        
        System.out.println();
    }
    
    /**
     * 错误处理对比
     */
    private void testErrorHandling() {
        System.out.println("5. 错误处理对比");
        System.out.println("----------------------------------------");
        
        // 测试无效模型
        String invalidModel = "non-existent-model-12345";
        
        // 现代客户端错误处理
        try {
            OllamaRequest request = new OllamaRequest(invalidModel, "测试");
            modernClient.generate(request);
            System.out.println("现代HttpClient: 预期错误但成功了");
        } catch (IOException e) {
            System.out.println("现代HttpClient: 正确捕获IOException - " + e.getMessage().substring(0, Math.min(50, e.getMessage().length())));
        } catch (Exception e) {
            System.out.println("现代HttpClient: 捕获其他异常 - " + e.getClass().getSimpleName());
        }
        
        // 传统客户端错误处理
        try {
            OllamaRequest request = new OllamaRequest(invalidModel, "测试");
            legacyClient.generate(request);
            System.out.println("传统URLConnection: 预期错误但成功了");
        } catch (IOException e) {
            System.out.println("传统URLConnection: 正确捕获IOException - " + e.getMessage().substring(0, Math.min(50, e.getMessage().length())));
        } catch (Exception e) {
            System.out.println("传统URLConnection: 捕获其他异常 - " + e.getClass().getSimpleName());
        }
        
        System.out.println();
    }
    
    /**
     * 截断字符串用于显示
     */
    private String truncateString(String str, int maxLength) {
        if (str == null) return "null";
        if (str.length() <= maxLength) return str;
        return str.substring(0, maxLength) + "...";
    }
    
    /**
     * 主方法，用于独立运行对比测试
     */
    public static void main(String[] args) {
        String baseUrl = "http://localhost:11434";
        String testModel = "qwen3:4b";
        
        if (args.length >= 1) {
            baseUrl = args[0];
        }
        if (args.length >= 2) {
            testModel = args[1];
        }
        
        System.out.println("使用配置:");
        System.out.println("  Ollama服务地址: " + baseUrl);
        System.out.println("  测试模型: " + testModel);
        System.out.println();
        
        OllamaClientComparison comparison = new OllamaClientComparison(baseUrl, testModel);
        comparison.runComparison();
    }
}
